package com.tgpms.interfaces.Request;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.util.*;

/**
 * @author eve
 * <p>
 * HTTP 请求列表
 */
//@Component
public class HttpClient {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final RestTemplate client = new RestTemplate(request());

    public static List<String> cookiesFull = new ArrayList<>();

    public static SimpleClientHttpRequestFactory request() {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(60 * 1000);
        requestFactory.setReadTimeout(60 * 1000);
        return requestFactory;
    }


    public String Login(String url, Map<String, Object> param, HttpMethod method) {
        HttpHeaders headers = new HttpHeaders();
        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
        for (Map.Entry<String, Object> keys : param.entrySet()) {
            map.add(keys.getKey(), keys.getValue());
        }
        //将请求头部和参数合成一个请求
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(map, headers);
        ResponseEntity<String> response = null;
        try {
            response = client.exchange(url, method, requestEntity, String.class);
            cookiesFull = response.getHeaders().get("Set-Cookie");
            logger.info("\n -> COOKIES WITH HEADERS FIR: " + cookiesFull);
        } catch (RestClientException e) {
            e.printStackTrace();
        }

        return response != null ? response.getBody() : null;
    }

    /**
     * POST 请求
     * 参数依次意思:
     * 1. URL：接口地址
     * 2. param: 接口携带的参数
     * 3. method: 接口请求方式（GET, POST, PUT, DELETE...）
     * 4. token: 每一次请求接口都需要携带Token，以便验证本次登录的有效性
     *
     * @param url
     * @param param
     * @return post
     */
    public String post(String url, Map<String, Object> param, HttpMethod method) {
        HttpHeaders headers = new HttpHeaders();
        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
        for (Map.Entry<String, Object> keys : param.entrySet()) {
            map.add(keys.getKey(), keys.getValue());
        }
        if (cookiesFull.size() > 0) {
            logger.info("\n -> COOKIES WITH HEADERS SEC: " + cookiesFull);
            headers.put(HttpHeaders.COOKIE, cookiesFull);
        }

        //将请求头部和参数合成一个请求
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(map, headers);
        ResponseEntity<String> response = null;
        try {
            response = client.exchange(url, method, requestEntity, String.class);
         } catch (RestClientException e) {
            e.printStackTrace();
        }

        return response != null ? response.getBody() : null;
    }
    
    
    /**
     * 特殊查询接口 POST 请求
     * 参数依次意思:
     * 1. URL：接口地址
     * 2. data: 接口携带的参数
     *
     * @param url
     * @param param
     * @return post
     */
    public String post(String url, ArrayList<BasicNameValuePair> data) {
    	String result;
		try {
			//UrlEncodedFormEntity这个类是用来把输入数据编码成合适的内容
			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(data,
					"UTF-8");//首先将参数设置为utf-8的形式，
			result = "";
			CloseableHttpClient httpClient = HttpClientBuilder.create().build();
			HttpPost post = new HttpPost(url);//post方式
			post.setHeader("Cookie",cookiesFull.get(0));
			post.setEntity(entity);//带上参数
			HttpResponse httpResponse = httpClient.execute(post);//响应结果
			System.out.println("响应状态为:" + httpResponse.getStatusLine());
			if (httpResponse.getStatusLine().getStatusCode() == 200) {//如果是200  表示成功
				result = EntityUtils.toString(httpResponse.getEntity());//把结果取出来  是一个STRING类型的
				System.out.println("响应数据为:" + result);
				return result;
			}else {
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} 
    }
    
    

    /**
     * mydeskLogin 登陆地址
     * 参数依次意思:
     * 1. URL：接口地址
     * 2. param: 接口携带的参数
     * 3. method: 接口请求方式（GET, POST, PUT, DELETE...）
     * 4. token: 每一次请求接口都需要携带Token，以便验证本次登录的有效性
     *
     * @param url
     * @param param
     * @return post
     */
    public String mydeskLogin(String url, Map<String, Object> param, HttpMethod method) {
        HttpHeaders headers = new HttpHeaders();
        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
        for (Map.Entry<String, Object> keys : param.entrySet()) {
            map.add(keys.getKey(), keys.getValue());
        }

        //将请求头部和参数合成一个请求
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(map, headers);
        ResponseEntity<String> response = null;
        try {
            response = client.exchange(url, method, requestEntity, String.class);
        } catch (RestClientException e) {
            e.printStackTrace();
        }

        return response != null ? response.getBody() : null;
    }


    /**
     * 解析 Cookie
     * <p>
     * Cookie 第一个
     * JSESSIONID=207F057E7D1030D68A23B434A4F5E3AF; Path=/vform-service; HttpOnly
     * <p>
     * Cookie 第二个
     * rememberMe=deleteMe; Path=/vform-service; Max-Age=0; Expires=Tue, 06-Aug-2019 11:16:42 GMT
     *
     * @param cookies
     */
    public void parsingCookie(List<String> cookies) {
        Map<String, String> map = new HashMap<>(16);
        for (String cookie : cookies) {
            // 按照分号分割
            String[] semicolon = cookie.split(";");
            for (String semi : semicolon) {

                // 按照等号分割
                String[] sign = semi.split("=");
                if (!semi.equals(" HttpOnly")) {
                    map.put(sign[0].replace(" ", ""), sign[1]);
                } else {
                    map.put(sign[0].replace(" ", ""), "");
                }
            }
        }
    }
}
